home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * *
- * Preliminary *
- * Amiga AppShell (tm) *
- * *
- * Copyright (c) 1990,1991 Commodore-Amiga, Inc. All Rights Reserved. *
- * *
- * This software and information is proprietary, preliminary, and *
- * subject to change without notice. *
- * *
- * DISCLAIMER *
- * *
- * THIS SOFTWARE IS PROVIDED "AS IS". *
- * NO REPRESENTATIONS OR WARRANTIES ARE MADE WITH RESPECT TO THE *
- * ACCURACY, RELIABILITY, PERFORMANCE, CURRENTNESS, OR OPERATION *
- * OF THIS SOFTWARE, AND ALL USE IS AT YOUR OWN RISK. *
- * NEITHER COMMODORE NOR THE AUTHORS ASSUME ANY RESPONSIBILITY OR *
- * LIABILITY WHATSOEVER WITH RESPECT TO YOUR USE OF THIS SOFTWARE. *
- * *
- * Non-Disclosure *
- * *
- * This information is not to be disclosed to any other company, *
- * individual or party. Discussion is to be restricted to CBM *
- * approved discussion areas, such as the closed conferences on bix; *
- * amiga.cert, amiga.com, amiga.beta/appshell. *
- * *
- ************************************************************************
- */
-
- /* clipiff.c
- * Simple IFF FTXT clipboard routines, requires iffparse.library version 36.
- * Copyright (C) 1990 Commodore-Amiga, Inc.
- * written by David N. Junod, 26-Aug-90
- *
- * Compiled with Lattice 'C' version 5.05.
- *
- * LC -cqfist -ms -v clipiff
- */
-
- #include <exec/types.h>
- #include <exec/libraries.h>
- #include <exec/memory.h>
- #include <exec/io.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <devices/clipboard.h>
- #include <libraries/iffparse.h>
- #include <utility/hooks.h>
- #include <clib/exec_protos.h>
- #include <clib/iffparse_protos.h>
- #include <pragmas/exec.h>
- #include <pragmas/iffparse.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "clipiff.h"
-
- extern struct Library *SysBase, *UtilityBase;
-
- #define CLIP_ERROR FALSE
-
- struct ClipManager *__asm AllocClip (VOID)
- {
- struct ClipManager *cm;
- ULONG hookEntry();
-
- /* Attempt to allocate the ClipManager structure */
- if (cm = (struct ClipManager *)
- AllocMem (sizeof (struct ClipManager), MEMF_CLEAR))
- {
- /* Are we using 2.0 or greater? */
- if (SysBase->lib_Version >= 36)
- {
- /* Initialize the hook */
- cm->cm_Hook.h_Entry = hookEntry;
- cm->cm_Hook.h_Data = (VOID *) 0xFACE;
- }
-
- /* Indicate that there isn't a hook installed */
- cm->cm_HookUnit = (-1L);
- }
-
- /* Return the initialized ClipManager */
- return (cm);
- }
-
- VOID __asm FreeClip (register __a1 struct ClipManager * cm)
- {
-
- /* Make sure we at least have a pointer */
- if (cm)
- {
- WORD i;
-
- /* See if there is a hook installed */
- if (cm->cm_HookUnit >= 0L)
- {
- /* Stop the hook */
- StopClipChangeHook (cm);
- }
-
- /* Shutdown each open clipboard unit */
- for (i = 0; i < MAX_UNITS; i++)
- CloseClip (cm->cm_Unit[i]);
-
- /* Free each open clipboard buffer */
- for (i = 0; i < MAX_UNITS; i++)
- FreeBuffer (cm->cm_Buff[i]);
-
- /* Free the clipboard manager */
- FreeMem (cm, sizeof (struct ClipManager));
-
- } /* End of if ClipManager */
- }
-
- struct ClipBuff * __asm ReadClip (
- register __a1 struct ClipManager * cm,
- register __d0 LONG iff_type,
- register __d1 LONG id)
- {
- struct ClipBuff *buffer = NULL;
- struct IFFHandle *iff = NULL;
-
- /* make sure we have a pointer at least */
- if (cm)
- {
- /* Make sure we have a valid clipboard unit */
- if ((id >= 0L) && (id < MAX_UNITS))
- {
- /* Open the requested clipboard unit if it isn't already */
- if (!(cm->cm_Unit[id]))
- {
- cm->cm_Unit[id] = OpenClip (id);
- }
-
- /* Free the buffer */
- FreeBuffer (cm->cm_Buff[id]);
- cm->cm_Buff[id] = NULL;
-
- /* Make sure we have a clipboard unit to work with */
- if (iff = cm->cm_Unit[id])
- {
- switch (iff_type)
- {
- case 0L: /* Default to FTXT */
- case ID_FTXT:
- buffer = ReadFTXT (iff);
- break;
-
- default:
- break;
- }
-
- /* assign the buffer */
- cm->cm_Buff[id] = buffer;
-
- } /* End of if unit available */
- } /* End of if >= 0 and < MAX_UNITS */
- } /* End of if ClipManager pointer */
-
- return (buffer);
- }
-
- LONG __asm QueryClip (
- register __a1 struct ClipManager * cm,
- register __d0 LONG unit,
- register __a2 ULONG *ctype,
- register __a3 ULONG *clipid)
- {
- LONG retval = FALSE;
-
- if (cm)
- {
- struct IFFHandle *iff;
-
- /* Open the requested clipboard unit if it isn't already */
- if (!(cm->cm_Unit[unit]))
- {
- cm->cm_Unit[unit] = OpenClip (unit);
- }
-
- /* Make sure we have a clipboard unit to work with */
- if (iff = cm->cm_Unit[unit])
- {
- struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
- struct IOClipReq *clipIO = &(cbh->cbh_Req);
- LONG cbuff[5] = {NULL};
-
- /* Read clipboard header */
- clipIO->io_Command = CMD_READ;
- clipIO->io_Error = 0;
- clipIO->io_ClipID = 0;
- clipIO->io_Offset = 0;
- clipIO->io_Data = (char *) cbuff;
- clipIO->io_Length = 20;
- DoIO (clipIO);
-
- /* Fill in the clip ID */
- *clipid = (ULONG) clipIO->io_ClipID;
-
- /* Clear the type field */
- *ctype = 0L;
-
- /* See if the read was successful */
- if ((clipIO->io_Actual >= 8L) && (cbuff[2] != ID_SPACE))
- {
- /* Fill in the type field */
- *ctype = (ULONG) cbuff[2];
- }
-
- /* indicate that we're done reading */
- clipIO->io_Offset = 0x7FFFFFF0;
- clipIO->io_Length = 1;
- clipIO->io_Data = NULL;
- DoIO (clipIO);
-
- /* Indicate success */
- retval = TRUE;
- }
- }
-
- return (retval);
- }
-
- /* This hook must do the least amount of work as possible. It is done on the
- * clipboard.device task frame */
- ULONG clipHook (struct Hook *h, VOID *o, struct ClipHookMsg *msg)
- {
- if (h->h_Data)
- {
- Signal ((struct Task *)h->h_Data, SIGBREAKF_CTRL_E);
- }
-
- return (0L);
- }
-
- LONG __asm StartClipChangeHook (
- register __a1 struct ClipManager * cm,
- register __d0 LONG unit)
- {
- LONG retval = FALSE;
-
- if (cm)
- {
- struct IFFHandle *iff;
-
- /* Open the requested clipboard unit if it isn't already */
- if (!(cm->cm_Unit[unit]))
- {
- cm->cm_Unit[unit] = OpenClip (unit);
- }
-
- /* Make sure we don't have any outstanding hooks */
- StopClipChangeHook (cm);
-
- /* Make sure we have a clipboard unit to work with */
- if (iff = cm->cm_Unit[unit])
- {
- struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
- struct IOClipReq *clipIO = &(cbh->cbh_Req);
- extern ULONG hookEntry();
-
- /* Fill out the IO request */
- clipIO->io_Command = CBD_CHANGEHOOK;
- clipIO->io_Data = (char *) &(cm->cm_Hook);
- clipIO->io_Length = 1;
-
- /* Prepare the hook */
- cm->cm_Hook.h_Entry = hookEntry;
- cm->cm_Hook.h_SubEntry = clipHook;
- cm->cm_Hook.h_Data = FindTask (NULL);
-
- /* Start the hook */
- if (DoIO (clipIO))
- {
- /* printf ("unable to set hook\n"); */
- }
- else
- {
- /* Indicate success */
- cm->cm_HookUnit = unit;
-
- retval = TRUE;
- }
- }
- }
-
- return (retval);
- }
-
- LONG __asm StopClipChangeHook (register __a1 struct ClipManager * cm)
- {
- LONG retval = FALSE;
-
- if (cm && (cm->cm_HookUnit >= 0L))
- {
- LONG unit = cm->cm_HookUnit;
- struct IFFHandle *iff;
-
- /* Open the requested clipboard unit if it isn't already */
- if (!(cm->cm_Unit[unit]))
- {
- cm->cm_Unit[unit] = OpenClip (unit);
- }
-
- /* Make sure we have a clipboard unit to work with */
- if (iff = cm->cm_Unit[unit])
- {
- struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
- struct IOClipReq *clipIO = &(cbh->cbh_Req);
-
- /* Fill out the IO request */
- clipIO->io_Command = CBD_CHANGEHOOK;
- clipIO->io_Data = (char *) &(cm->cm_Hook);
- clipIO->io_Length = 0;
-
- /* Start the hook */
- if (DoIO (clipIO))
- {
- /* printf ("unable to stop hook\n"); */
- }
- else
- {
- /* Indicate success */
- retval = TRUE;
- }
- }
-
- /* Indicate that the hook has been halted */
- cm->cm_HookUnit = (-1L);
- }
-
- return (retval);
- }
-
- LONG __asm WriteClip (
- register __a1 struct ClipManager * cm,
- register __a2 struct ClipBuff * buff,
- register __d0 LONG id)
- {
- LONG retval = 0L;
-
- /* make sure we have a pointer at least */
- if (cm && buff)
- {
- struct IFFHandle *iff = NULL;
-
- /* Make sure we have a valid clipboard unit */
- if ((id >= 0L) && (id < MAX_UNITS))
- {
- /* Open the requested clipboard unit if it isn't already */
- if (!(cm->cm_Unit[id]))
- cm->cm_Unit[id] = OpenClip (id);
-
- /* Make sure we have a clipboard unit to work with */
- if (iff = cm->cm_Unit[id])
- {
- switch (buff->b_Type)
- {
- case 0L: /* Default to FTXT */
- case ID_FTXT:
- retval = WriteFTXT (iff, buff->b_Buff);
- break;
-
- default:
- break;
- }
- } /* End of if unit available */
- } /* End of if >= 0 and < MAX_UNITS */
-
- /* Assign the clip ID assigned to this write */
- buff->b_ClipID = retval;
- } /* End of if ClipManager pointer */
-
- return (retval);
- }
-
- /****** clip/OpenClip *********************************************************
- *
- * NAME
- * OpenClip - Obtain an IFF handle on the desired clipboard unit.
- *
- * SYNOPSIS
- * handle = OpenClip ( clip_id );
- * d0 d0
- *
- * struct IFFHandle *handle;
- * LONG clip_id;
- *
- * FUNCTION
- * Obtain a handle on a particular clipboard unit for reading and
- * writing of data.
- *
- * INPUTS
- * clip_id - A number from 0 to 255, used to indicate the clipboard
- * unit to use. For normal useage, PRIMARY_CLIP should
- * be used.
- *
- * RETURNS
- * handle - Returns a valid IFFHandle to use for further access
- * or NULL if unable to access the requested unit.
- *
- * SEE ALSO
- * CloseClip()
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- struct IFFHandle *__asm OpenClip (register __d0 LONG id)
- {
- struct IFFHandle *iff = NULL;
-
- /* Allocate an IFF handle */
- if (iff = AllocIFF ())
- {
- /* Open the clipboard for access */
- if (iff->iff_Stream = (ULONG) OpenClipboard (id))
- {
- /* Initialize the handle as clipboard access */
- InitIFFasClip (iff);
- }
- else
- {
- /* Free the IFF handle */
- FreeIFF (iff);
- iff = NULL;
- }
- }
-
- return (iff);
- }
-
- /****** clip/CloseClip ********************************************************
- *
- * NAME
- * CloseClip - Close an IFF handle obtained by OpenClip().
- *
- * SYNOPSIS
- * CloseClip ( handle );
- * a0
- *
- * struct IFFHandle *handle;
- *
- * FUNCTION
- * Used to close a IFF handle opened by OpenClip() only.
- *
- * INPUTS
- * handle - A valid IFFHandle obtained by calling OpenClip().
- *
- * SEE ALSO
- * OpenClip()
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- VOID __asm CloseClip (register __a1 struct IFFHandle * iff)
- {
-
- /* Make sure that the handle points to something */
- if (iff)
- {
- /* Close the clipboard */
- if (iff->iff_Stream)
- CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream);
-
- /* Free the IFF handle */
- FreeIFF (iff);
- }
- }
-
- /****** clip/FreeBuffer *******************************************************
- *
- * NAME
- * FreeBuffer - Used to free a buffer returned by ReadClip().
- *
- * SYNOPSIS
- * FreeBuffer ( buffer );
- * a0
- *
- * struct ClipBuff *buffer;
- *
- * FUNCTION
- * This function is used to free the memory allocated by a call to
- * ReadClip().
- *
- * INPUTS
- * buffer - A valid buffer pointer returned by a call to ReadClip().
- *
- * SEE ALSO
- * ReadFTXT()
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- VOID __asm FreeBuffer (register __a1 struct ClipBuff * buff)
- {
-
- /* Make sure that buffer is a pointer, not an error */
- if ((LONG) buff > 0L)
- {
- /* Free the entire buffer */
- FreeMem ((APTR) buff, buff->b_Size);
- }
- }
-
- /****** clip/ReadFTXT *********************************************************
- *
- * NAME
- * ReadFTXT - Read the IFF handle for FTXT.
- *
- * SYNOPSIS
- * buffer = ReadFTXT ( handle );
- * d0 a0
- *
- * struct ClipBuff *buffer;
- * struct IFFHandle *handle;
- *
- * FUNCTION
- * Read the passed IFF handle for the first occurrance of FTXT CHRS
- * and returns the characters in a buffer.
- *
- * INPUTS
- * handle - A valid IFF handle, returned by OpenClip().
- *
- * RETURNS
- * buffer - If greater than zero, then it is a pointer to a ClipBuff
- * structure that contains the contents of the FTXT CHRS
- * chunk first encountered.
- *
- * If buffer is less than zero, then an error occurred and
- * the following macros are used to indicate the error.
- *
- * RC_EMPTY_CLIP \* clipboard is empty *\
- * RC_NOT_ENOUGH_MEMORY \* not enough memory *\
- * RC_COULDNT_READ \* couldn't read a chunk *\
- * RC_BAD_IFF \* clipboard contains a bad IFF *\
- * RC_INVALID_TYPE \* don't understand FORM type *\
- *
- * SEE ALSO
- * FreeBuffer()
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- LONG ftxtprops[] = {ID_FTXT, ID_AUTH, ID_FTXT, ID_NAME};
-
- struct ClipBuff *__asm
- ReadFTXT (register __a1 struct IFFHandle * iff)
- {
- struct ClipBuff *b = NULL;
- LONG error = 0L;
-
- /* Make sure that the handle points to something */
- if (iff)
- {
- struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
- struct IOClipReq *clipIO = &(cbh->cbh_Req);
-
- if (((struct Library *) IFFParseBase)->lib_Version < 36)
- {
- /* Bug workaround: clear io_Error field */
- clipIO->io_Error = 0;
-
- /* Bug workaround: Turn off the write flag */
- iff->iff_Flags &= ~IFFF_WRITE;
- }
-
- /* Open the IFF handle for reading */
- if (!(error = OpenIFF (iff, IFFF_READ)))
- {
- /* Declare the properties to search for */
- PropChunks (iff, ftxtprops, 2);
-
- /* Register the stop chunk */
- if ((error = StopChunk (iff, ID_FTXT, ID_CHRS)) == 0L)
- {
- /* Parse the file, stopping at a character chunk */
- error = ParseIFF (iff, IFFPARSE_SCAN);
- }
-
- /* Check the return value */
- if (error == IFFERR_EOF || error == IFFERR_NOTIFF)
- {
- b = (struct ClipBuff *) RC_EMPTY_CLIP;
- }
- else if (error != 0L)
- {
- b = (struct ClipBuff *) RC_BAD_IFF;
- }
- else
- {
- struct ContextNode *cn;
- LONG msize;
-
- /* Get information on the current chunk */
- if ((cn = CurrentChunk (iff)) && (cn->cn_Size > 0L))
- {
- /* Calculate the size of our buffer */
- msize = sizeof (struct ClipBuff) + cn->cn_Size + 1;
-
- /* Allocate a buffer to place our text in */
- if (b = (struct ClipBuff *) AllocMem (msize, MEMF_CLEAR))
- {
- /* Point the contents buffer at the right place */
- b->b_Buff = (VOID *) ((b) + 1);
-
- /* Read in the characters */
- if ((error = ReadChunkBytes (iff, b->b_Buff, cn->cn_Size))
- == cn->cn_Size)
- {
- /* Remember the buffer size */
- b->b_Size = msize;
-
- /* Remember the type of buffer */
- b->b_Type = ID_FTXT;
-
- /* Get the current clip ID */
- b->b_ClipID = clipIO->io_ClipID;
-
- #if 0
- struct StoredProperty *sp;
-
- /* Get the author information */
- if (sp = FindProp (iff, ID_FTXT, ID_AUTH))
- {
- msize = sp->sp_Size + 1L;
-
- if (b->b_Author = (STRPTR) AllocMem (msize, MEMF_CLEAR))
- {
- b->b_ASize = msize;
- strcpy (b->b_Author, sp->sp_Data);
- }
- }
-
- /* Get the project information */
- if (sp = FindProp (iff, ID_FTXT, ID_NAME))
- {
- msize = sp->sp_Size + 1L;
-
- if (b->b_Project = (STRPTR) AllocMem (msize, MEMF_CLEAR))
- {
- b->b_PSize = msize;
- strcpy (b->b_Project, sp->sp_Data);
- }
- }
- #endif
- }
- else
- {
- /* Free the buffer */
- FreeMem ((APTR) b, msize);
- b = (struct ClipBuff *) RC_COULDNT_READ;
- }
- } /* End of if allocate buffer */
- else
- {
- b = (struct ClipBuff *) RC_NOT_ENOUGH_MEMORY;
- }
-
- } /* End of get current chunk info */
- else
- {
- b = (struct ClipBuff *) RC_COULDNT_READ;
- }
-
- } /* End of handle parse */
-
- /* Say that we're done reading */
- CloseIFF (iff);
- }
- else
- {
- b = (struct ClipBuff *) error;
- }
-
- } /* End of if there is a handle */
-
- return (b);
- }
-
- /****** clip/WriteChunk *******************************************************
- *
- * NAME
- * WriteChunk - Used to write a text chunk.
- *
- * SYNOPSIS
- * error = WriteChunk ( handle, chunk, text );
- * d0 a0 d0 a1
- *
- * LONG error;
- * struct IFFHandle *handle;
- * LONG chunk;
- * STRPTR text;
- *
- * FUNCTION
- * This function is used to write out a text chunk, such as ANNO, AUTH
- * or CHRS.
- *
- * INPUTS
- * handle - A valid IFF handle, returned by OpenClip()
- *
- * chunk - A chunk type that supports text, such as ID_ANNO, ID_AUTH,
- * ID_CHRS, ID_(c) or ID_NAME.
- *
- * text - A pointer to a NULL terminated buffer that contains the
- * text to write.
- *
- * RETURNS
- * error - A value of zero indicates that no errors occurred. A non-
- * zero value indicates an error. Values are defined in
- * <libraries/iffparse.h>.
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- LONG __asm WriteChunk (
- register __a1 struct IFFHandle * iff,
- register __d0 LONG id,
- register __a2 STRPTR buffer)
- {
- LONG error = 0L;
- LONG clen = (LONG) strlen (buffer) + 1;
-
- if (buffer && (clen > 0L))
- {
- if ((error = PushChunk (iff, 0, id, -1L)) == 0L)
- {
- if ((error = WriteChunkBytes (iff, buffer, clen)) > 0L)
- {
- error = PopChunk (iff);
- }
- }
- }
-
- return (error);
- }
-
- /****** clip/WriteFTXT ********************************************************
- *
- * NAME
- * WriteFTXT - Write an IFF form that contains text.
- *
- * SYNOPSIS
- * error = WriteFTXT ( handle, text );
- * d0 a0 a1
- *
- * LONG error;
- * struct IFFHandle *handle;
- * STRPTR text;
- *
- * FUNCTION
- * This function is used to write an IFF form that contains text.
- *
- * INPUTS
- * handle - A valid IFF handle, returned by OpenClip()
- * text - A pointer to a NULL terminated buffer that contains the
- * text to write.
- *
- * RETURNS
- * error - A value of zero indicates that no errors occurred. A
- * negative number indicates an error (values are defined
- * in <libraries/iffparse.h>. A positive number indicates
- * the clip ID assigned to the clip.
- *
- * SEE ALSO
- * ReadFTXT()
- *
- **********************************************************************
- *
- * Created: 26-Aug-90, David N. Junod
- *
- */
-
- LONG __asm
- WriteFTXT (register __a1 struct IFFHandle * iff, register __a2 STRPTR buffer)
- {
- LONG retval = 0L;
-
- if (iff)
- {
- struct ClipboardHandle *cbh = (struct ClipboardHandle *) iff->iff_Stream;
- struct IOClipReq *clipIO = &(cbh->cbh_Req);
-
- if (((struct Library *) IFFParseBase)->lib_Version < 36)
- {
- /* Bug workaround: clear io_Error field */
- clipIO->io_Error = 0;
- }
-
- /* Open the IFF handle for writing */
- if ((retval = OpenIFF (iff, IFFF_WRITE)) == 0L)
- {
- /* Start writing the text ... */
- if ((retval = PushChunk (iff, ID_FTXT, ID_FORM, -1L)) == 0)
- {
- /* Write out the buffer as characters */
- WriteChunk (iff, ID_CHRS, buffer);
-
- /* Finish out the entire write */
- PopChunk (iff);
-
- /* Assign the clip ID */
- retval = clipIO->io_ClipID;
- }
-
- /* Say that we're done writing */
- CloseIFF (iff);
- }
- }
-
- return (retval);
- }
-